package com.bosicloud.cmb.ibp.account.config;


import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.sqs.AmazonSQSAsync;
import com.amazonaws.services.sqs.AmazonSQSAsyncClientBuilder;
import com.bosicloud.cmb.ibp.QueueNames;
import com.bosicloud.cmb.ibp.commom.properties.AWSProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.aws.messaging.config.QueueMessageHandlerFactory;
import org.springframework.cloud.aws.messaging.config.SimpleMessageListenerContainerFactory;
import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate;
import org.springframework.cloud.aws.messaging.listener.QueueMessageHandler;
import org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @author Jack Peng / ziliang.peng@bosicloud.com
 */
@Slf4j
@Configuration
@ComponentScan("com.bosicloud.cmb.ibp")
@EnableConfigurationProperties(AWSProperties.class)
public class AwsConfig {

    private final AWSProperties properties;

    public AwsConfig(AWSProperties properties) {
        this.properties = properties;
    }


    @Bean
    public AWSCredentialsProvider awsCredentialsProvider() {

        AWSCredentialsProvider provider = new DefaultAWSCredentialsProviderChain();

        log.info("### IBP Credentials Type : {} ", provider.getCredentials().getClass().getName());

        return provider;
    }

    @Bean
    public AmazonS3 amazonS3(AWSCredentialsProvider provider) {

        AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard()
                .withCredentials(provider)
                .withRegion(properties.getRegion().trim())
                .build();

        return amazonS3;
    }

    @Bean
    public AmazonSQSAsync amazonSQS(AWSCredentialsProvider provider, QueueNames queueNames) throws IllegalAccessException {

        AmazonSQSAsync sqsAsync = AmazonSQSAsyncClientBuilder.standard()
                .withCredentials(provider)
                .withRegion(properties.getRegion().trim())
                .build();

        sqsAsync.createQueue(queueNames.getRequest());
        sqsAsync.createQueue(queueNames.getResponseAccount());
        sqsAsync.createQueue(queueNames.getResponseApiManager());

        return sqsAsync;
    }

    @Bean
    public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSQSAsync) {

        return new QueueMessagingTemplate(amazonSQSAsync);
    }

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer(AmazonSQSAsync amazonSQSAsync) {
        SimpleMessageListenerContainer msgListenerContainer = simpleMessageListenerContainerFactory(amazonSQSAsync).createSimpleMessageListenerContainer();
        msgListenerContainer.setMessageHandler(queueMessageHandler(amazonSQSAsync));

        return msgListenerContainer;
    }

    @Bean
    public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory(AmazonSQSAsync amazonSQSAsync) {
        SimpleMessageListenerContainerFactory msgListenerContainerFactory = new SimpleMessageListenerContainerFactory();
        msgListenerContainerFactory.setAmazonSqs(amazonSQSAsync);
        msgListenerContainerFactory.setMaxNumberOfMessages(10);
        msgListenerContainerFactory.setWaitTimeOut(10);

        return msgListenerContainerFactory;
    }

    @Bean
    public QueueMessageHandler queueMessageHandler(AmazonSQSAsync amazonSQSAsync) {
        QueueMessageHandlerFactory queueMsgHandlerFactory = new QueueMessageHandlerFactory();
        queueMsgHandlerFactory.setAmazonSqs(amazonSQSAsync);

        QueueMessageHandler queueMessageHandler = queueMsgHandlerFactory.createQueueMessageHandler();

        return queueMessageHandler;
    }

}
